/*
 * Copyright 2025 The JA-SIG Collaborative. All rights reserved. distributed with this file and
 * available online at
 */
package com.lap.auth.application.project;

import com.lap.auth.application.project.assembler.ProjectAssembler;
import com.lap.auth.application.project.command.CreateProjectCmd;
import com.lap.auth.application.project.command.UpdateProjectCmd;
import com.lap.auth.application.project.dto.ProjectDto;
import com.lap.auth.application.project.dto.QueryProjectPageQuery;
import com.lap.auth.application.project.repository.ProjectQueryRepository;
import com.lap.auth.domain.api.repository.ApiRepository;
import com.lap.auth.domain.project.Project;
import com.lap.auth.domain.project.repository.ProjectRepository;
import com.lap.auth.domain.project.service.ProjectValidator;
import com.lap.framework.dto.page.PageResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 项目应用服务层
 *
 * <ol>
 *   <li>不谈业务规则，只谈基础规则（加密/解密是技术实现，业务不关注）
 *   <li>取数，赋值，对象转换到在这层执行
 *   <li>命名有规范，动词+领域名字
 *   <li>如查询比较多，建议分开领域QueryAppService,如:分页查询，分页查询返回关联字段
 * </ol>
 */
@RequiredArgsConstructor
@Service
public class ProjectAppService {

  private final ProjectAssembler projectAssembler;
  private final ProjectValidator projectValidator;
  private final ProjectRepository projectRepository;
  private final ApiRepository apiRepository;
  private final ProjectQueryRepository projectQueryRepository;

  public PageResponse<ProjectDto> queryProjectsByPage(QueryProjectPageQuery query) {
    return projectQueryRepository.findByConditionPaged(query);
  }

  public Integer createProject(CreateProjectCmd cmd) {
    Project project = projectAssembler.toDomain(cmd);
    projectValidator.validateContextUnique(project, false);
    return projectRepository.save(project);
  }

  public int updateProject(Integer id, UpdateProjectCmd cmd) {
    projectValidator.assertProjectExists(id);
    Project project = projectAssembler.toDomain(id, cmd);
    projectValidator.validateContextUnique(project, true);
    return projectRepository.save(project);
  }

  @Transactional(rollbackFor = Exception.class)
  public void deleteProject(Integer id) {
    Project project = projectValidator.assertProjectExists(id);
    projectRepository.deleteById(id);
    apiRepository.deleteByModule(project.getContext());
  }
}
